"""
测试前请修改/etc/gps.conf文件，将debug level 改为5，重启生效
"""

import serial
import time
import os
import sys
import random
import re
import subprocess
import threading


# 定义常量
DEBUG_PORT = "COM4"
AT_PORT = "COM51"
BAUDRATE = 115200
# 定义变量
at_serial = None
debug_serial = None
# 记录运行次数
runTimes = 0
# log文件
DEBUG_LOG = ""
ADB_LOG = ""
AT_LOG = ""


# 创建日志文件
def createLogFile():
    global DEBUG_LOG, ADB_LOG, AT_LOG
    timestamp = time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime())
    DEBUG_LOG = f"DEBUG_LOG_{timestamp}.log"
    ADB_LOG = f"ADB_LOG_{timestamp}.log"
    AT_LOG = f"AT_LOG_{timestamp}.log"

    with open(DEBUG_LOG, "w", encoding="utf-8") as file:
        file.write("DEBUG 日志开始记录...\n")

    with open(ADB_LOG, "w", encoding="utf-8") as file:
        file.write("ADB 日志开始记录...\n")

    with open(AT_LOG, "w", encoding="utf-8") as file:
        file.write("AT 日志开始记录...\n")


# 写日志
def write_log(log, logFile):
    with open(logFile, "a", encoding="utf-8") as file_object:
        file_object.write(
            str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
            + "\r\n"
            + log
            + "\r\n"
        )
        now_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        print("[" + now_time + "]" + " " + log)


# Send at instruction
def at_write(command, timeout, at_port_opened, at_result, RDY=0, CPIN=0):
    at_command = command.encode("UTF-8")
    at_port_opened.write(at_command)


# 读取at口返回
def at_read(serial_port, logFile=""):
    rec_str = ""
    while True:
        time.sleep(1)
        lenth = serial_port.inWaiting()
        if lenth > 0:
            rec_str = serial_port.read(size=lenth)
            try:
                rec_str = re.sub("\\x1b.*?m", "", rec_str.decode("UTF-8"), 0, re.I)
                if logFile != "":
                    with open(logFile, "a") as file_object:
                        rec_str = (
                            str(time.time())
                            + ":"
                            + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
                            + "\r\n"
                            + rec_str
                        )
                        file_object.write(
                            str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
                            + "\r\n"
                            + rec_str
                            + "\r\n"
                        )
                return rec_str
            except:
                return ""
        else:
            break
    return rec_str


# 登录设备
def loginDevice():
    global DEBUG_LOG
    # 确认登录失败的条件，或者，不可能失败
    while True:
        #   print("等待登录... ... ")
        write_log("等待登录... ... ", DEBUG_LOG)
        time.sleep(3)
        at_write("\r\n", 3, debug_serial, "OK")
        result = at_read(debug_serial)

        with open(DEBUG_LOG, "a") as file_object:
            file_object.write(result)

        if "login:" in result:
            at_write("root\r\n", 3, debug_serial, "OK")
            #    print("账号输入成功")
            write_log("账号输入成功", DEBUG_LOG)
            time.sleep(2)
            at_write("oelinux123\r\n", 3, debug_serial, "OK")
            #    print("密码输入成功")
            write_log("密码输入成功", DEBUG_LOG)
        elif "~ #" in result:
            #    print("登录成功")
            write_log("登录成功", DEBUG_LOG)
            break
        else:
            continue


# 检查debug口通信状态
def check_port_status():
    global debug_serial
    if debug_serial == None:
        try:
            debug_serial = serial.Serial(DEBUG_PORT, BAUDRATE)
        except:
            print("端口连接失败，请检查端口")
            sys.exit()


# 写入运行次数到日志
def writeRuntimesToLog():
    global runTimes
    with open(DEBUG_LOG, "a+") as file_object:
        file_object.write(
            "\r\n{} runtimes: {} {}\r\n".format("<" * 20, runTimes, ">" * 20)
        )
    #  print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
    with open(AT_LOG, "a+") as file_object:
        file_object.write(
            "\r\n{} runtimes: {} {}\r\n".format("<" * 20, runTimes, ">" * 20)
        )
    #  print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
    with open(ADB_LOG, "a+") as file_object:
        file_object.write(
            "\r\n{} runtimes: {} {}\r\n".format("<" * 20, runTimes, ">" * 20)
        )
    print("\r\n{} runtimes: {} {}\r\n".format("<" * 20, runTimes, ">" * 20))
    runTimes += 1


# 发送AT指令
def send_at_command(command):
    # 打开串口
    ser = serial.Serial(AT_PORT, BAUDRATE)
    ser.write((command + "\r\n").encode())
    ser.write(("\r\n").encode())
    time.sleep(6)
    response = ser.read_all().decode()
    ser.close()
    # write_log(f"at指令{command}执行结果:{response}",AT_LOG)
    with open(AT_LOG, "a", encoding="utf-8") as file_object:
        file_object.write(
            str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
            + "\r\n"
            + response
            + "\r\n"
        )
    return response


# 发送adb命令
def send_adb_command(command):
    try:
        # 使用 subprocess 模块执行 adb shell 命令
        # 开启adb root权限
        subprocess.run(["adb", "root"], capture_output=True, text=True)
        # 等待adb设备连接
        result = subprocess.run(
            ["adb", "shell", command], capture_output=True, text=True
        )
        with open(ADB_LOG, "a", encoding="utf-8") as file_object:
            file_object.write(
                str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
                + "\r\n"
                + result.stdout
                + "\r\n"
            )
        # 返回命令的输出结果
        return result.stdout
    except Exception as e:
        return str(e)


# 写入运行次数到日志
def writeRuntimesToLog():
    global runTimes
    with open(DEBUG_LOG, "a+") as file_object:
        file_object.write(
            "\r\n{} runtimes: {} {}\r\n".format("<" * 20, runTimes, ">" * 20)
        )
    print("\r\n{} runtimes: {} {}\r\n".format("<" * 20, runTimes, ">" * 20))
    runTimes += 1


# 设置GNSS参数
def set_gnss_parameters():
    write_log("设置GNSS参数", DEBUG_LOG)
    at_write("gnss --set fixRate 200 \r\n", 3, debug_serial, "OK")
    time.sleep(2)
    at_read(debug_serial, DEBUG_LOG)
    time.sleep(2)


# 保存logcat日志到文件
def save_logcat_to_file():
    write_log("保存logcat日志到文件", DEBUG_LOG)
    at_write("logcat -b main -f /usrdata/logcat.txt &\r\n", 3, debug_serial, "OK")
    time.sleep(2)


def check_gnrmc_unique_time(gnss_data_list):
    time_set = set()
    for data in gnss_data_list:
        match = re.match(r"\$GNRMC,([^,]*),", data)
        if match:
            utc_time = match.group(1)
            if utc_time in time_set:
                return False  # 存在重复的时间
            time_set.add(utc_time)

    return True  # 所有时间均唯一


def start_gnss(duration):
    write_log("启动GNSS", DEBUG_LOG)
    at_write("gnss --start\r\n", 3, debug_serial, "OK")
    time.sleep(50)

    gnss_results = []
    failure_detected = False  # 是否发生定位失败

    start_time = time.time()  # 开始时间
    end_time = start_time + duration  # 结束时间

    while time.time() < end_time:  # 持续到结束时间
        gnss_result = at_read(debug_serial, DEBUG_LOG)
        gnss_results.append(gnss_result)

        # 检测 RMC 和 GGA 的定位状态
        rmc_match = re.search(r"\$GNRMC,[^,]*,A,", gnss_result)  # 检测 RMC 定位
        gga_match = re.search(
            r"\$G[NP]GGA,(?:[^,]*,){5}(\d)", gnss_result
        )  # 匹配 GGA 第六字段（定位状态）

        # 判断是否定位成功
        if rmc_match or (
            gga_match and gga_match.group(1) in ["1", "2"]
        ):  # RMC 或 GGA 定位成功
            write_log("GNSS 定位成功", DEBUG_LOG)
        else:
            write_log("GNSS 定位失败", DEBUG_LOG)
            failure_detected = True  # 标记为失败
            break  # 立即退出循环

        time.sleep(1)  # 每秒获取一次
    if check_gnrmc_unique_time(gnss_results):
        write_log("GNRMC 时间无重复", DEBUG_LOG)
    else:
        write_log("GNRMC 时间有重复", DEBUG_LOG)
    # 检查最终状态
    if failure_detected:
        write_log("定位测试失败：持续时间内出现定位失败", DEBUG_LOG)
    else:
        write_log("定位测试成功：持续时间内未出现定位失败", DEBUG_LOG)

    # 返回 GNSS 数据和最终判定
    return gnss_results, not failure_detected


# 模块重启
def restart_module():
    at_write(chr(3), 3, debug_serial, "OK")
    write_log("重启模块", DEBUG_LOG)
    at_write("\r\nsys_reboot\r\n", 3, debug_serial, "OK")
    time.sleep(60)
    at_read(debug_serial, DEBUG_LOG)


# 初始化配置
duration_time = 600  # 10 分钟
check_port_status()
createLogFile()
print(f"DEBUG_LOG: {DEBUG_LOG}, ADB_LOG: {ADB_LOG}, AT_LOG: {AT_LOG}")
while True:
    loginDevice()
    writeRuntimesToLog()
    save_logcat_to_file()
    set_gnss_parameters()
    start_gnss(duration_time)
    restart_module()
